package com.madou.dbtool.redis.manager;

import com.madou.common.annotation.HideClass;
import com.madou.dbtool.redis.utils.BytesToStringUtil;
import redis.clients.jedis.*;

import java.util.*;

/**
 * @author miukoo
 * Redis 集群客户端
 */
@HideClass
public class ClusterRedisSourceManager implements RedisSourceManager {
    String host;
    int port;
    String password;
    JedisCluster cluster;
    DirectRedisSourceManager directRedisSourceManager;

    public ClusterRedisSourceManager(String host, int port){
        this(host,port,null);
    }

    public ClusterRedisSourceManager(String host,int port,String password){
        this(host,port,password,null);
    }
    public ClusterRedisSourceManager(String host,int port,String password,DirectRedisSourceManager directRedisSourceManager){
        this.host = host;
        this.port = port;
        this.password = parsePassword(password);;
        this.directRedisSourceManager = directRedisSourceManager;
    }



    private synchronized JedisCluster connection(){
        if(cluster==null) {
            Set<HostAndPort> nodes = new HashSet<>();
            nodes.add(new HostAndPort(host, port));
            DefaultJedisClientConfig.Builder builder = DefaultJedisClientConfig.builder();
            if(password!=null){
                builder.password(password);
            }
            DefaultJedisClientConfig jedisClientConfig =builder.build();
            cluster = new JedisCluster(nodes,jedisClientConfig);
            if(directRedisSourceManager==null) {
                directRedisSourceManager = new DirectRedisSourceManager(host, port, password);
            }
        }
        return  cluster;
    }

    public static void main(String[] args) {
        ClusterRedisSourceManager ds = new ClusterRedisSourceManager("192.168.56.102",6382);
        ds.connection();
        List<RedisNodeInfo> nodes = ds.getNodes();
        System.out.println(nodes);
    }

    @Override
    public int getDBCount() {
        return 1;
    }

    @Override
    public boolean isCluster() {
        return true;
    }

    @Override
    public List<RedisNodeInfo> getNodes() {
        return null;
    }

    @Override
    public Long getDBSize(int index) {
        connection();
        return directRedisSourceManager.getDBSize(0);
    }

    /**
     * 获取第一页的数据
     * @return
     */
    @Override
    public List<byte[]> getFirst(int index) {
        connection();
        return directRedisSourceManager.getFirst(index);
    }

    /**
     * 执行命令
     * @param commandText
     * @return
     */
    @Override
    public Object execute(int index,String commandText){
        connection();
        String[] temp = commandText.trim().split(" ");
        List<byte[]> args = new ArrayList<>();
        for (int i = 1; i < temp.length; i++) {
            if(temp[i]!=""&&temp[i]!=" "){
                args.add(BytesToStringUtil.string2Byte(temp[i]));
            }
        }
        byte[][] commandArgs = new byte[args.size()][];
        args.toArray(commandArgs);
        Protocol.Command command = Protocol.Command.valueOf(temp[0].toUpperCase(Locale.ROOT));
        return cluster.sendCommand(command, commandArgs);
    }

    /**
     * 执行一条命令
     * @param commandArgs
     * @return
     */
    @Override
    public Object execute(int index,Protocol.Command command, byte[][] commandArgs){
        connection();
        return cluster.sendCommand(command, commandArgs);
    }

    /**
     * 开启监控
     * @param jedisMonitor
     * @return
     */
    @Override
    public void monitor(JedisMonitor jedisMonitor){
    }

    @Override
    public RedisSourceManager cloneDirect() {
        return new DirectRedisSourceManager(host,port,password);
    }

    @Override
    public RedisSourceManager cloneCluster() {
        return new ClusterRedisSourceManager(host,port,password);
    }

    @Override
    public void close() {
        if(cluster!=null){
            cluster.close();
            cluster = null;
        }
    }

    @Override
    public String getDataSourceName() {
        return host+"-"+port;
    }



}
